import numpy as np

sentence_length = 20
path = r'/home/b8313/coding/music/music_essay/outputdata/pureGRU/otherGRU/genera_gru_{}.npy'


# 预处理中用于处理第4列数据的函数，将数值转化为以unit为单位最接近的数
def approximate(d):
    unit = 0.25
    flag = True
    if d < 0:
        flag = False
        d = -d
    quotient = int(d / unit)
    remainder = d % unit

    if flag:
        if remainder < unit / 2:
            return unit * quotient
        else:
            return unit * (quotient + 1)
    else:
        if remainder < unit / 2:
            return -(unit * quotient)
        else:
            return -(unit * (quotient + 1))


def pre_process(path):
    data = np.load(path, allow_pickle=True)

    data_T = data.T
    data_T[3] = np.round(data_T[3])

    data_T[5] = np.round(data_T[5])
    for pitch in range(0, len(data_T[5])):
        for sentence in range(0, len(data_T[5][pitch])):
            if data_T[5][pitch][sentence] < 0:
                data_T[5][pitch][sentence] = 0

    for pitch in range(0, len(data_T[4])):
        for sentence in range(0, len(data_T[4][pitch])):
            temp = approximate(data_T[4][pitch][sentence])
            if temp <= 0.25:
                temp = 0.25
            data_T[4][pitch][sentence] = temp

    data = data_T.T
    return data


# MIDI numbers span：平均每个句子的 midi数字跨度和（最大音高-最小音高）
def getMIDI_numbers_span(data):
    MIDI_numbers_spans = []

    for sentence in data:
        maxpitch = sentence[0][3]
        minpitch = sentence[0][3]
        for pitch in sentence:
            maxpitch = max(maxpitch, pitch[3])
            minpitch = min(minpitch, pitch[3])

        MIDI_numbers_span = maxpitch - minpitch
        MIDI_numbers_spans.append(MIDI_numbers_span)

    # print(MIDI_numbers_spans)
    mean = np.mean(MIDI_numbers_spans)
    return mean


# Number of Unique MIDI note in every song：每首歌一共生成了多少个不同的音高(一个文件500句为一首歌)
def getNumber_of_Unique_MIDI_note_in_every_song(data):
    y = []
    for sentence in data:
        for pitch in sentence:
            y.append(pitch[3])

    x = set(y)
    Number_of_Unique_MIDI_note = len(x)
    return Number_of_Unique_MIDI_note


# Number of Unique MIDI note in every sentence： 每句一共生成了多少个不同的音高
def getNumber_of_Unique_MIDI_note_in_every_sentence(data):
    Numbers_of_Unique_MIDI_note = []
    for sentence in data:
        y = []
        for pitch in sentence:
            y.append(pitch[3])

        x = set(y)
        Numbers_of_Unique_MIDI_note.append(len(x))

    mean = np.mean(Numbers_of_Unique_MIDI_note)
    return mean


# Number of rest in every sentence：平均每句出现休止符数量
def getNumber_of_rest_in_every_sentence(data):
    Numbers_of_rest_in_every_sentence = []
    for sentence in data:
        number_of_rest = 0
        for pitch in sentence:
            rest = pitch[5]
            if rest > 0:
                number_of_rest += 1

        Numbers_of_rest_in_every_sentence.append(number_of_rest)

    mean = np.mean(Numbers_of_rest_in_every_sentence)
    return mean


# Sum length of rest value in every sentence：平均每句的平均休止符长度(按中文意思)
def getSum_length_of_rest_value_in_every_sentence(data):
    Sum_length_of_rest_values = []
    for sentence in data:
        Sum_length_of_rest_value = 0
        for pitch in sentence:
            rest = pitch[5]
            Sum_length_of_rest_value += rest

        temp = Sum_length_of_rest_value / sentence_length
        Sum_length_of_rest_values.append(temp)

    mean = np.mean(Sum_length_of_rest_values)
    return mean


# sum time length of every sentence：每个句子的平均时间总长度【所有音符的音符长度与休止符长度和】
def getSum_time_length_of_every_sentence(data):
    Sum_time_length_of_sentences = []
    for sentence in data:
        Sum_time_length_of_every_sentence = 0
        for pitch in sentence:
            Sum_time_length_of_every_sentence += pitch[4] + pitch[5]

        Sum_time_length_of_sentences.append(Sum_time_length_of_every_sentence)

    mean = np.mean(Sum_time_length_of_sentences)
    return mean


# transitions between MIDI numbers相邻音符之间的跨度
def getTransitions_between_MIDI_numbers(data):
    transitions_between_MIDI_numbers = []
    for sentence in data:
        transition_between_MIDI_numbers = 0
        for pitch in range(0, sentence_length - 1):
            temp = sentence[pitch + 1][3] - sentence[pitch][3]
            temp = abs(temp)
            transition_between_MIDI_numbers += temp

        transition_between_MIDI_numbers = transition_between_MIDI_numbers / (sentence_length - 1)
        transitions_between_MIDI_numbers.append(transition_between_MIDI_numbers)

    mean = np.mean(transitions_between_MIDI_numbers)
    return mean


# 注意：此处的path为单个文件完整路径
def process1(path):
    data = pre_process(path)

    MIDI_numbers_span = getMIDI_numbers_span(data)
    print("MIDI_numbers_span: " + str(MIDI_numbers_span))

    Number_of_Unique_MIDI_note_in_every_song = getNumber_of_Unique_MIDI_note_in_every_song(data)
    print("Number_of_Unique_MIDI_note_in_every_song: " + str(Number_of_Unique_MIDI_note_in_every_song))

    Number_of_Unique_MIDI_note_in_every_sentence = getNumber_of_Unique_MIDI_note_in_every_sentence(data)
    print("Number_of_Unique_MIDI_note_in_every_sentence: " + str(Number_of_Unique_MIDI_note_in_every_sentence))

    Number_of_rest_in_every_sentence = getNumber_of_rest_in_every_sentence(data)
    print("Number_of_rest_in_every_sentence: " + str(Number_of_rest_in_every_sentence))

    Sum_length_of_rest_value_in_every_sentence = getSum_length_of_rest_value_in_every_sentence(data)
    print("Sum_length_of_rest_value_in_every_sentence: " + str(Sum_length_of_rest_value_in_every_sentence))

    Sum_time_length_of_every_sentence = getSum_time_length_of_every_sentence(data)
    print("Sum_time_length_of_every_sentence: " + str(Sum_time_length_of_every_sentence))

    Transitions_between_MIDI_numbers = getTransitions_between_MIDI_numbers(data)
    print("Transitions_between_MIDI_numbers: " + str(Transitions_between_MIDI_numbers))


# 获取平均值，此处的路径为待补充路径
def getMean(path):
    MIDI_numbers_spans = []
    Numbers_of_Unique_MIDI_note_in_every_song = []
    Numbers_of_Unique_MIDI_note_in_every_sentence = []
    Numbers_of_rest_in_every_sentence = []
    Sums_length_of_rest_value_in_every_sentence = []
    Sums_time_length_of_every_sentence = []
    Transitions_between_MIDI_numbers = []

    for i in range(0, 6):
        path1 = path.format(i)
        data = pre_process(path1)

        MIDI_numbers_span = getMIDI_numbers_span(data)
        Number_of_Unique_MIDI_note_in_every_song = getNumber_of_Unique_MIDI_note_in_every_song(data)
        Number_of_Unique_MIDI_note_in_every_sentence = getNumber_of_Unique_MIDI_note_in_every_sentence(data)
        Number_of_rest_in_every_sentence = getNumber_of_rest_in_every_sentence(data)
        Sum_length_of_rest_value_in_every_sentence = getSum_length_of_rest_value_in_every_sentence(data)
        Sum_time_length_of_every_sentence = getSum_time_length_of_every_sentence(data)
        Transition_between_MIDI_numbers = getTransitions_between_MIDI_numbers(data)

        MIDI_numbers_spans.append(MIDI_numbers_span)
        Numbers_of_Unique_MIDI_note_in_every_song.append(Number_of_Unique_MIDI_note_in_every_song)
        Numbers_of_Unique_MIDI_note_in_every_sentence.append(Number_of_Unique_MIDI_note_in_every_sentence)
        Numbers_of_rest_in_every_sentence.append(Number_of_rest_in_every_sentence)
        Sums_length_of_rest_value_in_every_sentence.append(Sum_length_of_rest_value_in_every_sentence)
        Sums_time_length_of_every_sentence.append(Sum_time_length_of_every_sentence)
        Transitions_between_MIDI_numbers.append(Transition_between_MIDI_numbers)

    print("Mean:")
    print("MIDI_numbers_span: " + str(np.mean(MIDI_numbers_spans)))

    print("Number_of_Unique_MIDI_note_in_every_song: " + str(np.mean(Numbers_of_Unique_MIDI_note_in_every_song)))

    print(
        "Number_of_Unique_MIDI_note_in_every_sentence: " + str(np.mean(Numbers_of_Unique_MIDI_note_in_every_sentence)))

    print("Number_of_rest_in_every_sentence: " + str(np.mean(Numbers_of_rest_in_every_sentence)))

    print("Sum_length_of_rest_value_in_every_sentence: " + str(np.mean(Sums_length_of_rest_value_in_every_sentence)))

    print("Sum_time_length_of_every_sentence: " + str(np.mean(Sums_time_length_of_every_sentence)))

    print("Transitions_between_MIDI_numbers: " + str(np.mean(Transitions_between_MIDI_numbers)))


# 同时处理epoch50_gen_data_0 —— epoch50_gen_data_5，此处的path为
# 形如"C:\\Users\\Ling\\Desktop\\essay\\data1\\epoch50_gen_data_{}.npy"的待补充路径
def process6(path):
    for i in range(0, 6):
        path1 = path.format(i)
        print(path1)
        process1(path1)
        print("")

    getMean(path)

def is_same(note1, note2) -> bool:
    if abs(note1 - note2) <= 1:
        return True
    else:
        return False


def cal_pitch(data):
    total_pitch = 0
    same_pitch = 0
    for j in range(data.shape[0]):
        for i in range(data.shape[1]):
            # print(data[j][i])
            total_pitch += 1
            if is_same(data[j][i][0], data[j][i][3]):
                same_pitch += 1
    return same_pitch / total_pitch


if __name__ == '__main__':


    da_sample = np.load(path.format(1), allow_pickle=True)
    process6(path)

    url_list = [[path.format(i), 0] for i in range(6)]





    main_sum = 0
    for item in url_list:
        data = np.load(item[0], allow_pickle=True)
        item[1] = cal_pitch(data)
        main_sum += item[1]

    print('DW is : {}'.format(main_sum / len(url_list)))
